package com.hunttown.mes.common.utils;

import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

/**
 * @title: Hex转字符串
 * @author: wangjunfu
 * @date: 2022年01月13日 14:47
 * @description:
 */
public class HexStringUtils {

    private static final char[] DIGITS_HEX = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

    private static char[] encodeHex(byte[] data) {
        int l = data.length;
        char[] out = new char[l << 1];
        for (int i = 0, j = 0; i < l; i++) {
            out[j++] = DIGITS_HEX[(0xF0 & data[i]) >>> 4];
            out[j++] = DIGITS_HEX[0x0F & data[i]];
        }
        return out;
    }

    private static byte[] decodeHex(char[] data) {
        int len = data.length;
        if ((len & 0x01) != 0) {
            throw new RuntimeException("字符个数应该为偶数");
        }
        byte[] out = new byte[len >> 1];
        for (int i = 0, j = 0; j < len; i++) {
            int f = toDigit(data[j], j) << 4;
            j++;
            f |= toDigit(data[j], j);
            j++;
            out[i] = (byte) (f & 0xFF);
        }
        return out;
    }

    private static int toDigit(char ch, int index) {
        int digit = Character.digit(ch, 16);
        if (digit == -1) {
            throw new RuntimeException("Illegal hexadecimal character " + ch + " at index " + index);
        }
        return digit;
    }

    //字符串转十六进制
    public static String toHexString(byte[] bs) {
        return new String(encodeHex(bs));
    }

    //十六进制还原字符串
    public static String hexString2Bytes(String hex) {
        return new String(decodeHex(hex.toCharArray()));
    }

    public static byte[] chars2Bytes(char[] bs) {
        return decodeHex(bs);
    }

    //使用十六进制的字符串转换成字节数组
    public static byte[] hexStrToBinaryStr(String hexString) {

        hexString = hexString.replaceAll(" ", "");

        int len = hexString.length();
        byte[] data = new byte[len / 2];

        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
                    + Character.digit(hexString.charAt(i + 1), 16));
        }

        return data;
    }

    //UTF8中文转GBK，再转Hex
    public static String utf8ToGbkToHex(String utf8Str) {
        try {
            //思路：先转为Unicode，再转为GBK，最后转Hex
            String utf8 = new String(utf8Str.getBytes(StandardCharsets.UTF_8));
            String unicode = new String(utf8.getBytes(), StandardCharsets.UTF_8);
            return toHexString(unicode.getBytes("GBK"));
        } catch (Exception ex) {
            ex.printStackTrace();
            return "";
        }
    }

    //public static void main(String[] args) {
        //String hexStr = "65010389163020008F4102143839383631313231323239303335303539313933000A12E88F16";

        //String restoreStr = hexString2Bytes(hexStr);
        //System.out.println("十六进制还原字符串：" + restoreStr);

        //int len = 38;
        //byte[] hexByte = new byte[len];

        //for (int i = 0; i < len; i++) {
        //    String str = hexStr.substring(i * 2, i * 2 + 2);
        //    System.out.println("str->" + str);
        //    byte[] b16 = HexStringUtils.hexStrToBinaryStr(str);
        //    System.out.println("bt->" + b16[0]);

        //    hexByte[i] = b16[0];
        //}

        //System.out.println(toHexString(hexByte));

        //try {
        //    String test = "验票成功";

        //    //String gbk = utf8ToGbk("验票成功");
        //    String utf8 = new String(test.getBytes(StandardCharsets.UTF_8));
        //    String unicode = new String(utf8.getBytes(), StandardCharsets.UTF_8);
        //    String S1 = toHexString(unicode.getBytes("GBK"));
        //    System.out.println("S1：" + S1);

        //    //String result = URLEncoder.encode(gbk, "GBK");
        //    //System.out.println("GBK:" + result);
        //    //System.out.println("转回去：" + new String(gbk.getBytes("gbk"), StandardCharsets.UTF_8));

        //    String test_gbk_utf8 = new String(test.getBytes(StandardCharsets.UTF_8), "gbk");
        //    String S2 = toHexString(test_gbk_utf8.getBytes("gbk"));
        //    System.out.println("S2：" + S2);

        //    //System.out.println(test_gbk_utf8);
        //    //String test_utf8_gbk = new String(test_gbk_utf8.getBytes("gbk"), StandardCharsets.UTF_8);
        //    //System.out.println(test_utf8_gbk);

        //} catch (Exception ex) {
        //    ex.printStackTrace();
        //}
    //}
}
